#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
服务器监控服务
监控服务器状态和性能
"""

import asyncio
import psutil
from typing import Dict, Any, List
from datetime import datetime


class ServerMonitor:
    """服务器监控服务"""
    
    def __init__(self):
        self.running = False
        self.monitor_task = None
        self.callbacks = []
        
    async def start(self):
        """启动监控"""
        if self.running:
            return
            
        self.running = True
        self.monitor_task = asyncio.create_task(self._monitor_loop())
        
    async def stop(self):
        """停止监控"""
        if not self.running:
            return
            
        self.running = False
        
        if self.monitor_task:
            self.monitor_task.cancel()
            try:
                await self.monitor_task
            except asyncio.CancelledError:
                pass
            finally:
                self.monitor_task = None
                
    def add_callback(self, callback):
        """添加回调函数"""
        self.callbacks.append(callback)
        
    def remove_callback(self, callback):
        """移除回调函数"""
        if callback in self.callbacks:
            self.callbacks.remove(callback)
            
    async def _monitor_loop(self):
        """监控循环"""
        while self.running:
            try:
                # 收集系统信息
                system_info = self._get_system_info()
                
                # 触发回调
                for callback in self.callbacks:
                    try:
                        if asyncio.iscoroutinefunction(callback):
                            await callback(system_info)
                        else:
                            callback(system_info)
                    except Exception:
                        pass
                        
                await asyncio.sleep(5)
                
            except asyncio.CancelledError:
                break
            except Exception:
                await asyncio.sleep(10)
                
    def _get_system_info(self) -> Dict[str, Any]:
        """获取系统信息"""
        # CPU使用率
        cpu_percent = psutil.cpu_percent(interval=1)
        
        # 内存信息
        memory = psutil.virtual_memory()
        
        # 磁盘信息
        disk_usage = psutil.disk_usage('/')
        
        # 网络信息
        net_io = psutil.net_io_counters()
        
        return {
            "timestamp": datetime.now().isoformat(),
            "cpu": {
                "usage_percent": cpu_percent,
                "core_count": psutil.cpu_count(),
                "load_avg": psutil.getloadavg() if hasattr(psutil, 'getloadavg') else None
            },
            "memory": {
                "total": memory.total,
                "available": memory.available,
                "used": memory.used,
                "percent": memory.percent
            },
            "disk": {
                "total": disk_usage.total,
                "used": disk_usage.used,
                "free": disk_usage.free,
                "percent": (disk_usage.used / disk_usage.total) * 100
            },
            "network": {
                "bytes_sent": net_io.bytes_sent,
                "bytes_recv": net_io.bytes_recv,
                "packets_sent": net_io.packets_sent,
                "packets_recv": net_io.packets_recv
            }
        }
        
    def get_system_status(self) -> Dict[str, Any]:
        """获取当前系统状态"""
        return self._get_system_info()
        
    def get_process_list(self) -> List[Dict[str, Any]]:
        """获取进程列表"""
        processes = []
        
        for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
            try:
                processes.append({
                    "pid": proc.info['pid'],
                    "name": proc.info['name'],
                    "cpu_percent": proc.info['cpu_percent'],
                    "memory_percent": proc.info['memory_percent']
                })
            except (psutil.NoSuchProcess, psutil.AccessDenied):
                continue
                
        return processes


# 全局监控实例
_server_monitor = None

def get_server_monitor():
    """获取服务器监控实例"""
    global _server_monitor
    if _server_monitor is None:
        _server_monitor = ServerMonitor()
    return _server_monitor

async def start_server_monitor():
    """启动服务器监控"""
    monitor = get_server_monitor()
    await monitor.start()

async def stop_server_monitor():
    """停止服务器监控"""
    monitor = get_server_monitor()
    await monitor.stop()